using Microsoft.Maui.Handlers;

#if WINDOWS
using Microsoft.Web.WebView2.Core;
using Microsoft.Maui.Platform;
using System.Text;
#endif

#if ANDROID
using Android.Webkit;
using AndroidX.WebKit;
using Microsoft.Maui.Platform;
#endif

#if IOS || MACCATALYST
using WebKit;
using Foundation;
using Microsoft.Maui.Platform;
#endif

namespace Mark.Handlers
{
    public class CustomWebViewHandler : WebViewHandler
    {
        private const string LocalHostName = "appdir";
        private const string BaseUrl = $"https://{LocalHostName}/";

        protected override void ConnectHandler(object platformView)
        {
            base.ConnectHandler(platformView);

#if WINDOWS
            SetupWindowsRequestInterception();
#elif ANDROID
            SetupAndroidRequestInterception();
#elif IOS || MACCATALYST
            SetupIOSRequestInterception();
#endif
        }

#if WINDOWS
        private async void SetupWindowsRequestInterception()
        {
            if (PlatformView is MauiWebView mauiWebView)
            {
                await mauiWebView.EnsureCoreWebView2Async();
                
                // 设置虚拟主机名映射
                var applicationPath = GetApplicationPath();
                mauiWebView.CoreWebView2.SetVirtualHostNameToFolderMapping(
                    LocalHostName,
                    applicationPath,
                    CoreWebView2HostResourceAccessKind.Allow);

                // 添加Web资源请求处理
                mauiWebView.CoreWebView2.WebResourceRequested += OnWebResourceRequested;
                mauiWebView.CoreWebView2.AddWebResourceRequestedFilter($"{BaseUrl}*", CoreWebView2WebResourceContext.All);

                // 导航事件处理（安全考虑）
                mauiWebView.CoreWebView2.NavigationStarting += OnNavigationStarting;
            }
        }

        private void OnWebResourceRequested(object sender, CoreWebView2WebResourceRequestedEventArgs e)
        {
            try
            {
                var uri = new Uri(e.Request.Uri);
                if (uri.Host != LocalHostName)
                    return;

                var filePath = uri.LocalPath.TrimStart('/');
                var fileContent = GetLocalFileContent(filePath);
                
                if (fileContent != null)
                {
                    var contentType = GetContentType(filePath);
                    var stream = new MemoryStream(Encoding.UTF8.GetBytes(fileContent));
                    
                    e.Response = ((MauiWebView)PlatformView).CoreWebView2.Environment.CreateWebResourceResponse(
                        stream, 200, "OK", $"Content-Type: {contentType}");
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"WebView资源请求处理错误: {ex.Message}");
            }
        }

        private void OnNavigationStarting(object sender, CoreWebView2NavigationStartingEventArgs e)
        {
            if (PlatformView is MauiWebView mauiWebView)
            {
                var uri = new Uri(e.Uri);
                if (uri.Host != LocalHostName)
                {
                    // 导航到外部URL时清除虚拟主机映射（安全考虑）
                    mauiWebView.CoreWebView2.ClearVirtualHostNameToFolderMapping(LocalHostName);
                }
                else
                {
                    // 重新设置映射
                    var applicationPath = GetApplicationPath();
                    mauiWebView.CoreWebView2.SetVirtualHostNameToFolderMapping(
                        LocalHostName,
                        applicationPath,
                        CoreWebView2HostResourceAccessKind.Allow);
                }
            }
        }

        private string GetApplicationPath()
        {
            try
            {
                if (Windows.ApplicationModel.Package.Current != null)
                    return Windows.ApplicationModel.Package.Current.InstalledLocation.Path;
            }
            catch
            {
                // 非打包应用
            }
            return AppContext.BaseDirectory;
        }
#endif

#if ANDROID
        private void SetupAndroidRequestInterception()
        {
            if (PlatformView is MauiWebView mauiWebView)
            {
                var customWebViewClient = new CustomWebViewClient(this);
                mauiWebView.SetWebViewClient(customWebViewClient);
            }
        }

        private class CustomWebViewClient : MauiWebViewClient
        {
            private readonly CustomWebViewHandler _handler;

            public CustomWebViewClient(CustomWebViewHandler handler) : base(handler)
            {
                _handler = handler;
            }

            public override WebResourceResponse ShouldInterceptRequest(Android.Webkit.WebView view, IWebResourceRequest request)
            {
                try
                {
                    var uri = Android.Net.Uri.Parse(request.Url.ToString());
                    if (uri.Host == LocalHostName)
                    {
                        var filePath = uri.Path?.TrimStart('/');
                        var fileContent = _handler.GetLocalFileContent(filePath);
                        
                        if (fileContent != null)
                        {
                            var contentType = _handler.GetContentType(filePath);
                            var stream = new MemoryStream(Encoding.UTF8.GetBytes(fileContent));
                            return new WebResourceResponse(contentType, "UTF-8", stream);
                        }
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine($"Android WebView资源请求处理错误: {ex.Message}");
                }

                return base.ShouldInterceptRequest(view, request);
            }
        }
#endif

#if IOS || MACCATALYST
        private void SetupIOSRequestInterception()
        {
            if (PlatformView is MauiWKWebView mauiWebView)
            {
                var config = mauiWebView.Configuration;
                var handler = new CustomUrlSchemeHandler(this);
                config.SetUrlSchemeHandler(handler, LocalHostName);
            }
        }

        private class CustomUrlSchemeHandler : NSObject, IWKUrlSchemeHandler
        {
            private readonly CustomWebViewHandler _handler;

            public CustomUrlSchemeHandler(CustomWebViewHandler handler)
            {
                _handler = handler;
            }

            public void StartUrlSchemeTask(WKWebView webView, IWKUrlSchemeTask urlSchemeTask)
            {
                try
                {
                    var url = urlSchemeTask.Request.Url;
                    var filePath = url.Path?.TrimStart('/');
                    var fileContent = _handler.GetLocalFileContent(filePath);
                    
                    if (fileContent != null)
                    {
                        var contentType = _handler.GetContentType(filePath);
                        var data = NSData.FromString(fileContent, NSStringEncoding.UTF8);
                        var response = new NSHttpUrlResponse(url, 200, "1.1", new NSDictionary<NSString, NSString>
                        {
                            [new NSString("Content-Type")] = new NSString(contentType)
                        });
                        
                        urlSchemeTask.DidReceiveResponse(response);
                        urlSchemeTask.DidReceiveData(data);
                        urlSchemeTask.DidFinish();
                    }
                    else
                    {
                        var error = NSError.FromDomain("FileNotFound", 404, null);
                        urlSchemeTask.DidFailWithError(error);
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine($"iOS WebView资源请求处理错误: {ex.Message}");
                    var error = NSError.FromDomain("InternalError", 500, null);
                    urlSchemeTask.DidFailWithError(error);
                }
            }

            public void StopUrlSchemeTask(WKWebView webView, IWKUrlSchemeTask urlSchemeTask)
            {
                // 清理资源
            }
        }
#endif

        private string? GetLocalFileContent(string? filePath)
        {
            try
            {
                if (string.IsNullOrEmpty(filePath))
                    return null;

                using var stream = FileSystem.OpenAppPackageFileAsync(filePath).Result;
                using var reader = new StreamReader(stream);
                return reader.ReadToEnd();
            }
            catch
            {
                return null;
            }
        }

        private string GetContentType(string filePath)
        {
            var extension = Path.GetExtension(filePath).ToLowerInvariant();
            return extension switch
            {
                ".html" => "text/html",
                ".css" => "text/css",
                ".js" => "application/javascript",
                ".json" => "application/json",
                ".png" => "image/png",
                ".jpg" or ".jpeg" => "image/jpeg",
                ".gif" => "image/gif",
                ".svg" => "image/svg+xml",
                ".ico" => "image/x-icon",
                ".mp4" => "video/mp4",
                ".mp3" => "audio/mpeg",
                ".pdf" => "application/pdf",
                ".txt" => "text/plain",

                _ => "application/octet-stream"
            };
        }
    }
}